import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.junit.Test;

/**
 * @author linke
 * @version 1.0
 * @className: shiroTest01
 * @description: shiro测试
 * @date 2021/11/19 20:30
 */
public class ShiroTest01 {
    /**
     * 模拟固定配置查询权限
     * classpath:my.ini"
     */
    @Test
    public void test01(){
        //创建安全管理器工厂，读取指定配置文件
        Factory<SecurityManager> factory=
                new IniSecurityManagerFactory("classpath:my.ini");
        //获取安全管理器
        SecurityManager securityManager = factory.getInstance();
        //将安全管理器设置到当前环境中
        SecurityUtils.setSecurityManager(securityManager);
        //创建subject
        Subject subject = SecurityUtils.getSubject();
        //认证就是登录，输入账号密码
        UsernamePasswordToken token = new UsernamePasswordToken("a", "aaa");

        //认证前状态
        System.out.println("调用login前"+subject.isAuthenticated());//false
        try {
            //登录认证  在自定义的myRealm中查出来的数据进行比对     具体实现过程可看自定义的认证方法
            subject.login(token);
        }catch (UnknownAccountException e) {
            System.out.println("用户名不存在");
        }catch (IncorrectCredentialsException e) {
            System.out.println("密码错误");
        }catch (AuthenticationException e) {
            System.out.println("认证错误");
        }
        //认证后状态
        System.out.println("调用login后"+subject.isAuthenticated());//true

        //在控制台，查看角色和权限，是通过调用方法。
        //整合到Web以后，添加注解，注解底层会自动调用判断方法
        System.out.println("role1:"+subject.hasRole("role1"));
        System.out.println("role2:"+subject.hasRole("role2"));
        System.out.println("user:select:"+subject.isPermitted("user:select"));
        System.out.println("teacher:select:"+subject.isPermitted("teacher:select"));
        System.out.println("a:b:"+subject.isPermitted("a:b"));

        //check权限检查方法，没有权限抛出异常

        //subject.checkRole("role1");
        //subject.checkPermission("user:select");

        //退出
        subject.logout();
        System.out.println("调用logout后"+subject.isAuthenticated());//false
    }

    /**
     * 模拟从数据库中 查询获得权限
     * classpath:Realm.ini
     */
    @Test
    public void test02(){
        //创建安全管理器工厂，读取指定配置文件
        Factory<SecurityManager> factory=
                new IniSecurityManagerFactory("classpath:Realm.ini");
        //获取安全管理器
        SecurityManager securityManager = factory.getInstance();
        //将安全管理器设置到当前环境中
        SecurityUtils.setSecurityManager(securityManager);
        //创建subject
        Subject subject = SecurityUtils.getSubject();
        //认证就是登录，输入账号密码
        UsernamePasswordToken token = new UsernamePasswordToken("a", "aaa");

        //认证前状态
        System.out.println("调用login前"+subject.isAuthenticated());//false
        try {
            //登录认证  在自定义的myRealm中查出来的数据进行比对     具体实现过程可看自定义的认证方法
            subject.login(token);
        }catch (UnknownAccountException e) {
            System.out.println("用户名不存在");
        }catch (IncorrectCredentialsException e) {
            System.out.println("密码错误");
        }catch (AuthenticationException e) {
            System.out.println("认证错误");
        }
        //认证后状态
        System.out.println("调用login后"+subject.isAuthenticated());//true

        //在控制台，查看角色和权限，是通过调用方法。
        //整合到Web以后，添加注解，注解底层会自动调用判断方法

        //调用授权方法返回的权限 进行控制
        System.out.println("user:select:"+subject.isPermitted("user:select"));
        System.out.println("teacher:select:"+subject.isPermitted("teacher:select"));
        System.out.println("a:b:"+subject.isPermitted("a:b"));



        //退出
        subject.logout();
        System.out.println("调用logout后"+subject.isAuthenticated());//false
    }

}
